﻿using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Messaging;
using HslCommunication;
using HslCommunication.Profinet.Siemens;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows;
using TransControlSystem.Dao;
using TransControlSystem.Model;
using TransControlSystem.ViewModel.Common;
using TransControlSystem.ViewModel.Common.Command;

namespace TransControlSystem.ViewModel
{
    /// <summary>
    /// 通讯测试后台逻辑
    /// </summary>
    public class CommunicationTestViewModel : ViewModelBase
    {
        /// <summary>
        /// 西门子对象
        /// </summary>
        SiemensS7Net siemens = null;
        /// <summary>
        /// PLC连接对象 
        /// </summary>
        OperateResult connect = null;
        /// <summary>
        /// PLC地址
        /// </summary>
        private readonly string PlcAddress = PlcHelper.GetPlcAddress();
        /// <summary>
        /// 标签列表  
        /// </summary>
        private List<TagInfo> IsReadOnlyList = null;
        /// <summary>
        /// 编辑值命令
        /// </summary>
        public DelegateCommand EditValueCommand { get; set; }
        /// <summary>
        /// 是否要关闭窗口
        /// </summary>
        private bool toClose = false;
        /// <summary>
        /// 是否要关闭窗口
        /// </summary>
        public bool ToClose
        {
            get
            {
                return toClose;
            }
            set
            {
                toClose = value;
                if (toClose)
                {
                    RaisePropertyChanged("ToClose");
                }
            }
        }
        /// <summary>
        /// 是否起启动读PLC
        /// </summary>
        private bool isReadingPlc;
        /// <summary>
        /// 是否起启动读PLC
        /// </summary>
        public bool IsReadingPlc
        {
            get { return isReadingPlc; }
            set
            {
                isReadingPlc = value;
                RaisePropertyChanged("IsReadingPlc");
            }

        }

        //private Visibility readPlcStatus1;
        ///// <summary>
        ///// 是否显示启动测试按钮
        ///// </summary>
        //public Visibility ReadPlcStatus1
        //{
        //    get
        //    {
        //        return readPlcStatus1;
        //    }
        //    set
        //    {
        //        readPlcStatus1 = value;
        //        RaisePropertyChanged("ReadPlcStatus1");
        //    }
        //}
        public DelegateCommand StartUpCommand { get; set; }

        /// <summary>
        /// 构造方法
        /// </summary>
        public CommunicationTestViewModel()
        {
            //使用委托初始化开启监控命令
            StartUpCommand = new DelegateCommand()
            {
                ExecuteActionObj = new Action<object>(StartUpHandler)
            };

            EditValueCommand = new DelegateCommand()
            {
                ExecuteActionObj = new Action<object>(EditValueHandler)
            };
            IsReadingPlc = false;

            //注册刷新标签列表消息
            Messenger.Default.Register<NotificationMessage>(this, (nm) =>
            {
                if (nm.Notification == "ComTestReLoadTagList")
                {
                    ReLoadPlcValue();
                }
            });

        }

        /// <summary>
        /// 连接PLC
        /// </summary>
        private void comTest()
        {
            // 西门子PLC通讯，指定PLC的ip地址和端口号
            siemens = new SiemensS7Net(SiemensPLCS.S1500, PlcAddress);
            // 连接对象
            connect = siemens.ConnectServer();
            if (!connect.IsSuccess)
            {
                WindowManager.ShowWarning("警告", "与PLC连接中断，请检查网络通讯是否正常！");
            }
            else
            {
                string sql = "select * from TagInfo order by orderNo";
                IsReadOnlyList = DapperTools.Query<TagInfo>(sql);
                if (IsReadOnlyList.Count > 0)
                {
                    ReLoadPlcValue();
                }
            }
        }

        private void StartUpHandler(object obj)
        {
            comTest();
        }

        /// <summary>
        /// 编辑值处理程序
        /// </summary>
        /// <param name="obj">参数</param>
        private void EditValueHandler(object obj)
        {
            TagInfo TagInfo = (TagInfo)obj;
            WindowManager.ShowEditValue("EditValueWindow", TagInfo);
        }

        ///// <summary>
        ///// 监听器
        ///// </summary>
        //private void Listenner()
        //{
        //    while (true)
        //    {
        //        if (isReadingPlc)
        //        {
        //            if (!connect.IsSuccess)
        //            {
        //                WindowManager.ShowWarning("警告", "连接PLC失败请检查网络。");
        //                return;
        //            }
        //            else
        //            {
        //                ReLoadPlcValue();
        //            }
        //            // 两次读取的时间间隔
        //            Thread.Sleep(1000);
        //        }
        //    }
        //}
        /// <summary>
        /// 通讯队列
        /// </summary>
        private ObservableCollection<TagInfo> communicationList1;
        /// <summary>
        /// 通讯队列
        /// </summary>
        public ObservableCollection<TagInfo> CommunicationList1
        {
            get { return communicationList1; }
            set
            {
                communicationList1 = value;
                RaisePropertyChanged("CommunicationList1");
            }
        }
        /// <summary>
        /// 根据类型使用不同方式获取值
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        private string GetSiemensValByTagInfo(TagInfo param)
        {
            string val = null;
            if (param.ValueType == "Bool")
            {
                val = siemens.ReadBool(param.Address).Content.ToString();
            }
            else if (param.ValueType == "DInt")
            {
                val = siemens.ReadInt32(param.Address).Content.ToString();
            }
            else if (param.ValueType == "Int")
            {
                val = siemens.ReadInt16(param.Address).Content.ToString();
            }
            return val;
        }
        /// <summary>
        /// 刷新列表 
        /// </summary>
        private void ReLoadPlcValue()
        {
            ObservableCollection<TagInfo> TempCommunicationList = new ObservableCollection<TagInfo>();
            for (int i = 0; i < IsReadOnlyList.Count; i++)
            {
                IsReadOnlyList[i].Value = GetSiemensValByTagInfo(IsReadOnlyList[i]);
                Application.Current.Dispatcher.Invoke((Action)delegate ()
                {
                    TempCommunicationList.Add(IsReadOnlyList[i]);
                });
            }
            CommunicationList1 = TempCommunicationList;
        }
    }
}
